package {
	import flash.display.*;
	import mx.controls.Tree;
	import mx.controls.treeClasses.*;
	import mx.collections.*;
	import mx.controls.CheckBox;
	import mx.controls.listClasses.*;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import mx.events.FlexEvent;
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.xml.*;
	
	import mx.core.IDataRenderer;
	

	public class CheckTreeRenderer extends TreeItemRenderer{
        protected var myImage:Shape;
		protected var myCheckBox:CheckBox;
		static private var STATE_SCHRODINGER:String = "schrodinger";
		static private var STATE_CHECKED:String = "checked";
		static private var STATE_UNCHECKED:String = "unchecked";
	    
        public function CheckTreeRenderer () {
			super();
			mouseEnabled = false;
		}
		private function toggleParents(item:Object, tree:Tree, state:String):void{
			if (item == null){
				return;
			}else{
				item.@state = state;
				toggleParents(tree.getParentItem(item), tree, getState(tree, tree.getParentItem(item)));
			}
		}
		
		private function toggleChildren(item:Object, tree:Tree, state:String):void{
			if (item == null){
				return;
			}else{
				item.@state = state;
				var treeData:ITreeDataDescriptor = tree.dataDescriptor;
				if (treeData.hasChildren(item)){
					var children:ICollectionView = treeData.getChildren (item);
					var cursor:IViewCursor = children.createCursor();
					while (!cursor.afterLast){
						toggleChildren(cursor.current, tree, state);
						cursor.moveNext();
					}
				}
			}
		}
		
		private function getState(tree:Tree, parent:Object):String{
			var noChecks:int = 0;
			var noCats:int = 0;
			var noUnChecks:int = 0;
			if (parent != null){
				var treeData:ITreeDataDescriptor = tree.dataDescriptor;
				var cursor:IViewCursor = treeData.getChildren(parent).createCursor();
				while (!cursor.afterLast){
					if (cursor.current.@state == STATE_CHECKED){
						noChecks++;
					}else if (cursor.current.@state == STATE_SCHRODINGER){
						noCats++;
					}else{
						noUnChecks++
					}
					cursor.moveNext();
				}
			}
			if ((noChecks > 0 && noUnChecks > 0) || (noCats > 0)){
				return STATE_SCHRODINGER;
			}else if (noChecks == 0){
				return STATE_UNCHECKED;
			}else{
				return STATE_CHECKED;
			}
		}
		private function imageToggleHandler(event:MouseEvent):void{
			myCheckBox.selected = !myCheckBox.selected;
			checkBoxToggleHandler(event);
		}
		private function checkBoxToggleHandler(event:MouseEvent):void{
			if (data){
				var myListData:TreeListData = TreeListData(this.listData);
				var selectedNode:Object = myListData.item;
				var tree:Tree = Tree(myListData.owner);
				var toggle:Boolean = myCheckBox.selected;
				if (toggle){
					toggleChildren(data, tree, STATE_CHECKED);
				}else{
					toggleChildren(data, tree, STATE_UNCHECKED);
				}
				var parent:Object = tree.getParentItem(data);
				toggleParents (parent, tree, getState(tree, parent));
			}
		}
		
		override protected function createChildren():void{
			super.createChildren();
			myCheckBox = new CheckBox();
			myCheckBox.setStyle( "verticalAlign", "middle" );
			myCheckBox.addEventListener( MouseEvent.CLICK, checkBoxToggleHandler );
			addChild(myCheckBox);
			myImage = new Shape();
	    	myImage.graphics.beginFill(0x000000, 0.2);
	    	myImage.graphics.drawRoundRect(3, 0, 8, 8, 3);
	    	myImage.graphics.endFill();
			myImage.addEventListener( MouseEvent.CLICK, imageToggleHandler );
			addChild(myImage);
	    }	

		private function setCheckState(value:Object):void{
			if (value.@state == STATE_CHECKED){
				myCheckBox.selected = true;
			}else{
				myCheckBox.selected = false;
			}
		}	    
		override public function set data(value:Object):void{
			super.data = value;
			setCheckState (value);
			if(TreeListData(super.listData).item.@type == 'dimension'){
			    setStyle("fontStyle", 'italic');
			}else{
				if (this.parent != null){
					var _tree:Tree = Tree(this.parent.parent);
		    		_tree.setStyle("defaultLeafIcon", null);
		  		}
				setStyle("fontStyle", 'normal');
			}
	    }

	   override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
	        if(super.data){
			    if (super.icon != null){
				    myCheckBox.x = super.icon.x + 3;
				    myCheckBox.y = 9;
				    super.icon.x = myCheckBox.x + myCheckBox.width + 16;
				    super.label.x = super.icon.x + super.icon.width + 3;
				}else{
				    myCheckBox.x = super.label.x + 3;
				    myCheckBox.y = 9;
				    super.label.x = myCheckBox.x + myCheckBox.width + 16;
				}
				//myImage
			    if (data.@state == STATE_SCHRODINGER){
			    	myImage.alpha = 1;
			    	myImage.x = myCheckBox.x;
			    	myImage.y = myCheckBox.y - 4;
			    }else{
			    	myImage.alpha = 0;
			    }
			}
	    }
	}
}